from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _

class ModuleType(models.Model):
    ANONYMOUS = 1
    AUTHENTICATED = 2
    AVAILABILITY_CHOICES = (
        (ANONYMOUS & AUTHENTICATED, _('All users')),
        (AUTHENTICATED, _('Authenticated users only')),
        (ANONYMOUS, _('Anonymous users only')),
    )
    app_label = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    is_enabled = models.BooleanField(default=False)
    is_default = models.BooleanField(default=False)
    availability = models.SmallIntegerField(choices=AVAILABILITY_CHOICES, default=0)
    cache_timeout = models.PositiveIntegerField(default=0)
    default_position = models.PositiveIntegerField(default=1)

    def for_class(cls, module_class):
        return ModuleType.objects.get_or_create(
            app_label=module_class.__module__.split('.')[-2],
            name=module_class.__name__,
        )[0]
    for_class = classmethod(for_class)

    def __unicode__(self):
        return '%s.%s' % (self.app_label, self.name)

class Module(models.Model):
    user = models.ForeignKey(User)
    type = models.ForeignKey(ModuleType)
    position = models.PositiveIntegerField()

    def preferences(self):
        if not hasattr(self, '_preferences'):
            self._preferences = dict((str(p.name), p.value) for p in self.preference_set.all())
        return self._preferences
    preferences = property(preferences)

    def save(self):
        """
        Save this object, then save any modified preferences.
        """
        if not self.position:
            # Default to the end of the list
            self.position = len(self.user.module_set.all()) + 1

        super(Module, self).save()

        prefs = dict((p.name, p) for p in self.preference_set.all())
        for name, value in self.preferences.items():
            if name in prefs and prefs[name] != value:
                # The value has changed, so save it to the database
                prefs[name].value = value
                prefs[name].save()
            elif name not in prefs:
                # The value was not yet stored, so create it
                self.preference_set.create(name=name, value=value)

    class Meta:
        ordering = ('position',)
        unique_together = (('user', 'position'),)

class Preference(models.Model):
    module = models.ForeignKey(Module)
    name = models.CharField(max_length=255)
    value = models.CharField(max_length=255)

    class Meta:
        unique_together = (('module', 'name'),)
